﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using Fcdbas.WinUI.Forms;
using Fcdbas.Core.DataAccess;
using Fcdbas.Core.Xml;
using Fcdbas.Core.Serialization.Json;
using Fcdbas.Biz;
using Fcdbas.WinUI.Common;
using Fcdbas.Core;
using DevExpress.XtraSplashScreen;
using System.IO;
namespace Fcdbas.WinUI.Forms
{
    public partial class LoginForm : XtraForm
    {
        bool isActivited = false;
       // DataSet dsSqlInit = new DataSet();
        string sSqlInit = System.IO.Directory.GetCurrentDirectory() + @"\SQL.xml";
        string sUserInfo = System.IO.Directory.GetCurrentDirectory() + @"\User.dat";
        //string stLinkTable = "Data_Links";
        string stPwdKey = "PassWord20131030";
        //DataTable dtLinkTable = new DataTable();
        ConnectionStringSettings cons;
        private List<FndSession> dataLinks;
        private List<LogonUser> Users;
        private string dbType = "MySql";
        private static string LinkName = "Local";
        private bool IsReLogon = false;
        public LoginForm()
        {
            InitializeComponent();
           // this.Load += new System.EventHandler(this.LoginForm_Load);
        }
        public LoginForm(bool IsReLogon)
        {
            InitializeComponent();
            this.IsReLogon = IsReLogon;
            // this.Load += new System.EventHandler(this.LoginForm_Load);
        }
        private void LoginForm_Load(object sender, EventArgs e)
        {
            //可以用对象直接处理，不用表那么麻烦
            bool bInit = true;
            if (System.IO.File.Exists(sSqlInit))
            {
                bInit = true;
                try
                {
                    dataLinks = sSqlInit.ToXmlFileEntity<List<FndSession>>();
                }
                catch (Exception ex)
                {
                    bInit = false;
                }
                if (bInit)
                {
                    foreach (FndSession dlink in dataLinks)
                    {
                        cboDataBaseSelect.Properties.Items.Add(dlink.LINK_NAME);
                    }
                }
            }
            if (System.IO.File.Exists(sUserInfo))
            {
                try
                {
                    string str = Fcdbas.Core.Util.FileHelper.GetFileContent(sUserInfo);
                    Users = str.FromJson(typeof(List<LogonUser>)) as List<LogonUser>;
                    if (Users != null)
                    {
                        foreach (LogonUser fs in Users)
                        {
                            var s1 = (from dt in dataLinks
                                      where dt.LINK_NAME == fs.LINK_NAME && dt.USER_ID == fs.USER_ID
                                      select dt).FirstOrDefault();
                            if (s1 != null)
                            {
                                s1.USER_ID = fs.USER_ID;
                                s1.USER_PWD = fs.USER_PWD;
                                s1.IsLast = fs.IsLast;
                                s1.IsRoot = fs.IsRoot;
                            }


                        }
                    }
                    else
                    {
                        Users = new List<LogonUser>();
                    }
                }
                catch (Exception ex)
                {

                }

            }
            else
            {
                Users = new List<LogonUser>();
            }
            if(!bInit)
            {
                dataLinks = new List<FndSession>();
                foreach (string type in DAL.ConnStrs.Keys)
                {
                    cboDataBaseSelect.Properties.Items.Add(type);
                    ConnectionStringSettings cons = DAL.ConnStrs[dbType];
                    DbConnectionStringBuilder conBuilder = new DbConnectionStringBuilder();
                    cmbAuth.SelectedIndex = 0;
                    conBuilder.ConnectionString = cons.ConnectionString;
                    FndSession dl = new FndSession();
                    dl.LINK_NAME = type;
                    dl.TYPE = type;
                    dl.Server = conBuilder["Server"].ToString();
                    dl.Database = conBuilder["Database"].ToString(); 
                    dl.Port = int.Parse(conBuilder["Port"].ToString());
                    dataLinks.Add(dl);
                   
                }
            }
             LogonUser  f = (from fs in Users
                                 where fs.IsLast == true
                                 select fs).FirstOrDefault();
            if (!IsReLogon)
            {
               
                if (f != null)
                {
                    cboDataBaseSelect.SelectedItem = f.LINK_NAME;
                    LinkName = f.LINK_NAME;
                }
                else
                {
                    cboDataBaseSelect.SelectedIndex = 0;
                    LinkName = cboDataBaseSelect.EditValue.ToString();
                }
               
            }
            else
            {
                cboDataBaseSelect.SelectedItem = LinkName;
                cmbAuth.SelectedIndex = 0;
                cboDataBaseSelect.Properties.ReadOnly = true;
            }
            
                //var s = (from dt in Users
                //         where dt.LINK_NAME == LinkName && 
                //         select dt).FirstOrDefault();
                if (f != null && !string.IsNullOrEmpty(f.USER_ID) && !string.IsNullOrEmpty(f.USER_PWD))
                {
                    txtUserName.Text = f.USER_ID;
                    txtPassWord.Text = Fcdbas.Core.Security.DataHelper.Descrypt(f.USER_PWD, stPwdKey);
                    chkSavePassWord.Checked = true;
                    btnOK.Focus();
                }
                else
                {
                    txtUserName.Focus();
                    txtUserName.SelectAll();
                }
           
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.Hide();
            SplashScreenManager.ShowForm(this, typeof(FndSplashScreen), true, true, false);
            SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress,"开始加载程序集");
            //保存用户信息
            
            FndSession dt = dataLinks.Find(p => p.LINK_NAME == LinkName);
            if (Users != null)
            {
                foreach (LogonUser fs in Users)
                {
                    fs.IsLast = false;
                }
            }
            dt.USER_ID = txtUserName.Text;
           
           // dt.IsLast = true;
            cons = DAL.ConnStrs[dbType];
            DbConnectionStringBuilder conBuilder = new DbConnectionStringBuilder();
            conBuilder.ConnectionString = cons.ConnectionString;
            if (dbType.ToUpper() == "MYSQL")
            {
                conBuilder["Uid"] = txtUserName.Text;
                conBuilder["Pwd"] = txtPassWord.Text;
                conBuilder["Server"] = dt.Server;
                conBuilder["Database"] = dt.Database;
                conBuilder["Port"] = dt.Port;
                DAL.AddConnStr(dbType, conBuilder.ConnectionString, null, "MySql.Data.MySqlClient");
            }
            else
            {
                conBuilder["User ID"] = txtUserName.Text;
                conBuilder["Password"] = txtPassWord.Text;
                DAL.AddConnStr(dbType, conBuilder.ConnectionString, null, "System.Data.OracleClient");
            }
            if (cSessionManager.IsRemote)
            {
                AppEnvironment.Session.USER_ID = txtUserName.Text;
                AppEnvironment.Session.USER_PWD = txtPassWord.Text;
                AppEnvironment.Session.Language = cboLanguage.Text;
                SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "用户登录");
                if (!UserLogon())
                    return;
            }
            else
            {
                DAL dal = DAL.Create(dbType);
                try
                {
                    SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "登录数据库");
                    dal.Session.Open();
                    dal.Session.ReConnection += new EventHandler(Session_ReConnection);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("用户或者密码不对，请重新输入！");
                    SplashScreenManager.CloseForm(false);
                    this.Show();
                    txtUserName.Focus();
                    return;
                }
            }
            string sLicCheck = LicensesCheck();
            if (sLicCheck.Substring(0, 1) == "1")
            {
                if (sLicCheck.Length > 1)
                {
                    MessageBox.Show(sLicCheck.Split(':')[1]);
                }
            }
            else
            {
                MessageBox.Show(sLicCheck);
                this.Show();
                txtUserName.Focus();
                return;
            }
           
            if (Users == null)
                Users = new List<LogonUser>();
            var user = (from u in Users
                        where u.USER_ID == dt.USER_ID && u.LINK_NAME == dt.LINK_NAME
                        select u).FirstOrDefault();
            if (user == null)
            {
                user = new LogonUser();
                user.LINK_NAME = dt.LINK_NAME;
                   
                Users.Add(user);

            }
            user.IsLast = true;
                
            user.USER_ID = dt.USER_ID;
            //密码加密保存
            if (chkSavePassWord.Checked)
            {
                string stPassWord = txtPassWord.Text;
                stPassWord = Fcdbas.Core.Security.DataHelper.Encrypt(stPassWord, stPwdKey);
                dt.USER_PWD = stPassWord;
                user.USER_PWD = dt.USER_PWD;
            }
            else
                user.USER_PWD = "";
            user.LastLogonDate = DateTime.Now;
            if (cmbAuth.SelectedIndex == 0)
                user.IsRoot = false;
            else
                user.IsRoot = true;
            
           
           
            //不需要保存
            //dataLinks.ToXmlFile(sSqlInit);
            string content = Users.ToJson();
            if (user.USER_ID.ToUpper() == "ADMIN")
                user.IsRoot = true;
            Fcdbas.Core.Util.FileHelper.GenerateFile(sUserInfo, content, "");
            AppEnvironment.Session.CONNECTION = conBuilder.ConnectionString;
            AppEnvironment.Session.USER_ID = txtUserName.Text;
            AppEnvironment.Session.USER_PWD = txtPassWord.Text;
            AppEnvironment.Session.Language = cboLanguage.Text;
            AppEnvironment.Session.IsRoot = user.IsRoot;
            AppEnvironment.Session.Server = dt.Server;
            AppEnvironment.Session.Database = dt.Database;
            //AppEnvironment.Session.
            SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "初始化会话");
            if (!FndSession_Init())
            {
                SplashScreenManager.CloseForm(false);
                this.Show();
                return;
            }
            SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "加载用户配置");
            SysCache.DownLoadFndUserProfile(AppEnvironment.Session.USER_ID);
            SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "加载用户权限");
            SysCache.DownLoadFndUserSecurity(AppEnvironment.Session.USER_ID);
            SysCache.DownLoadFndEnumerate();
            SplashScreenManager.Default.SendCommand(LoadStatus.ShowProgress, "加载系统设置");
            SysCache.DownLoadFndVpdPolicy(AppEnvironment.Session.USER_ID);
            AppEnvironment.LoadOptions();

            //if (AppEnvironment.Session.USER_ID.ToLower() == "root" || AppEnvironment.Session.USER_ID.ToLower() == "hc")
            //    AppEnvironment.Session.IsRoot = true;
            //else
            //    AppEnvironment.Session.IsRoot = false;
            FndDAL.InitFndDataSource();
            
            

            this.Close();
        }

        static void Session_ReConnection(object sender, EventArgs e)
        {
            FndSession_Init();
        }
        private bool UserLogon()
        {
            DAL.Create(dbType);
            return true;
            //存储过程有错
            string sSql = "FndUser_CheckUser(:identity_,:load_attr_)";
            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("identity_", AppEnvironment.Session.USER_ID);
            dic.Add("load_attr_", AppEnvironment.Session.GetAttr());
            if (cSessionManager.RemoteSQLExecute(sSql, dic))
                return true;
            else
            {
                MessageBox.Show(cSessionManager.GetSqlLastError());
                return false;
            }
        }
        private static bool FndSession_Init()
        {
           // LicensesCheck();
            Dictionary<string,object> dic = new Dictionary<string,object> ();
            string sSql = "FndSession_Init(:attr_)";
            dic.Add("attr_",AppEnvironment.Session.GetAttr());
            SalString result = "";
            SalBoolean res = false;
            if (cSessionManager.IsRemote)
            {
                res = cSessionManager.RemoteSQLExecute(sSql, dic);
                if (!res)
                {
                     result = cSessionManager.GetSqlLastError();
                }
            }
            else
            {
                cSessionManager.DbTransactionBegin();
                res = cSessionManager.DbMySQLBlock(sSql, dic);
                if (!res)
                {
                    result = cSessionManager.GetSqlLastError();
                    cSessionManager.DbTransactionClear();
                }
                else
                    cSessionManager.DbTransactionEnd();
            }
            if (!res)
            {
                MessageBox.Show(result);
            }
            return res;
        }

        private string LicensesCheck()
        {
            List<FndLicenses> dataLicenses = new List<FndLicenses>();
            string sLicensesFile = System.IO.Directory.GetCurrentDirectory() + @"\licenses.lic";
            string sRtnStr = "1";
            if (System.IO.File.Exists(sLicensesFile))
            {
                //dataLicenses = sLicensesFile.ToXmlFileEntity<List<FndLicenses>>();
                FileStream aFile = new FileStream(sLicensesFile, FileMode.Open);
                StreamReader sr = new StreamReader(aFile);
                string strLine = sr.ReadToEnd();
                sr.Close();
                strLine = Fcdbas.Core.Security.DataHelper.Descrypt(strLine, stPwdKey);
                dataLicenses = XmlHelper.ToXmlEntity<List<FndLicenses>>(strLine);
            }
            else
            {
                return "未找到授权文件，请联系供应商！";
            }
            SalString sSql = "SELECT concat(uuid(),';',now())";
            string sLincens = cSessionManager.GetUserFunctionValue<string>(sSql, false);
            string[] sLicGrp = sLincens.Split(';')[0].Split('-');
            string sLicCurr = sLicGrp[sLicGrp.Length - 1].ToString();
            string sLicEntUUID = Fcdbas.Core.Security.DataHelper.Encrypt(sLicCurr, stPwdKey);
            string sLicEntYear = Fcdbas.Core.Security.DataHelper.Encrypt("2018", stPwdKey);
            var s = (from dt in dataLicenses
                     where dt.LIC_KEY == sLicEntUUID
                     select dt).FirstOrDefault();
            if (s != null && !string.IsNullOrEmpty(s.EXPIRATION_DATE))
            {
                DateTime dtNowDate = new DateTime(int.Parse(sLincens.Split(';')[1].Split('-')[0]), int.Parse(sLincens.Split(';')[1].Split('-')[1]), int.Parse(sLincens.Split(';')[1].Split('-')[2].Split(' ')[0]));
                string sExpDate = Fcdbas.Core.Security.DataHelper.Descrypt(s.EXPIRATION_DATE, stPwdKey);
                DateTime dtExpDate = new DateTime(int.Parse(sExpDate.Split('/')[0]), int.Parse(sExpDate.Split('/')[1]), int.Parse(sExpDate.Split('/')[2]),23,59,59);
                if (dtNowDate >dtExpDate)
                {
                    return "已过授权有效日期，请联系供应商！";
                }
                TimeSpan ts = dtExpDate - dtNowDate;
                if (ts.Days < 15)
                {
                    sRtnStr = string.Format("1:授权有效日期小于{0}天，请及时联系供应商",new string[]{(ts.Days+1).ToString().Trim()});
                }
            }
            else
            {
                return "授权码不正确，请联系供应商！";
            }
            sSql = "select count(*) FROM information_schema.processlist where user not in ('root') ";
            string sSessionCount = cSessionManager.GetUserFunctionValue<string>(sSql, false);
            if (int.Parse(sSessionCount) > int.Parse(Fcdbas.Core.Security.DataHelper.Descrypt(s.LICENSES, stPwdKey)))
            {
                return "授权连接数超出限制，请联系供应商！";
            }
            return sRtnStr;
        }

        private void LoginForm_Activated(object sender, EventArgs e)
        {
            if (isActivited == false)
            {
               
                isActivited = true;
            }
        }

        private void LoginForm_Shown(object sender, EventArgs e)
        {
            
        }

        private void GetUserMsg(string dbType)
        {
            string sPassword;
            FndSession dl = dataLinks.Find(p => p.TYPE == dbType && p.LINK_NAME == LinkName);
            if (dl == null)
                return;
            txtUserName.Properties.Items .Clear();
            var user = from u in Users
                       where u.LINK_NAME == dl.LINK_NAME
                       select u;
            LogonUser lstU = null;
            if(user != null)
            {
                foreach (LogonUser u in user.ToList())
                {
                    txtUserName.Properties.Items.Add(u.USER_ID);
                    if (u.IsLast)
                        lstU = u;
                }
            }
            if (lstU != null)
            {
                txtUserName.Text = lstU.USER_ID;
                sPassword = lstU.USER_PWD;
                if (lstU.IsRoot)
                    cmbAuth.SelectedIndex = 1;
                else
                    cmbAuth.SelectedIndex = 0;
            }
            else
            {
                if (dl.IsRoot)
                    cmbAuth.SelectedIndex = 1;
                else
                    cmbAuth.SelectedIndex = 0;
                txtUserName.Text = dl.USER_ID;
                sPassword = dl.USER_PWD;
            }
            
            
            if (sPassword.Trim() == "")
            {
                txtPassWord.Text = "";
            }
            else
            {
                txtPassWord.Text = Fcdbas.Core.Security.DataHelper.Descrypt(sPassword, stPwdKey);
            }
        }

        private void chkLanguage_CheckedChanged(object sender, EventArgs e)
        {
            cboLanguage.Enabled=chkLanguage.Checked;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.No;
            this.Close();
        }

        private void cboDataBaseSelect_SelectedIndexChanged(object sender, EventArgs e)
        {
            LinkName  = cboDataBaseSelect.EditValue.ToString();
            GetUserMsg(dbType);
        }

        private void LoginForm_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                btnOK_Click(this, EventArgs.Empty);
        }

        private void txtUserName_SelectedIndexChanged(object sender, EventArgs e)
        {
            var user = (from u in Users
                        where u.LINK_NAME == LinkName && u.USER_ID == txtUserName.Text 
                       select u).FirstOrDefault();
            if (user != null)
            {
                if (user.USER_ID.ToUpper() == "ADMIN")
                    user.IsRoot = true;
                string sPassword = user.USER_PWD;
                if (sPassword.Trim() == "")
                {
                    txtPassWord.Text = "";
                    chkSavePassWord.Checked = false;
                }
                else
                {
                    txtPassWord.Text = Fcdbas.Core.Security.DataHelper.Descrypt(sPassword, stPwdKey);
                    chkSavePassWord.Checked = true;
                }
                if (user.IsRoot)
                    cmbAuth.SelectedIndex = 1;
                else
                    cmbAuth.SelectedIndex = 0;
            }
        }
    }
}
